package haiyan.common.security;

import java.security.Key;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;

import haiyan.common.Base64;
import haiyan.common.exception.Warning;

public class DataDesUtil {

	private static DataDesUtil des;

	private static String KEY_LOCK = "suddenzhou";

	private Key key;

	private DataDesUtil() {
		setKey(KEY_LOCK);
	}

	/**
	 * 根据参数生成生成密匙KEY
	 * 
	 * @param strKey
	 */
	public void setKey(String strKey) {
		try {
			KeyGenerator generator = KeyGenerator.getInstance("DES");
			generator.init(new SecureRandom(strKey.getBytes()));
			this.key = generator.generateKey();
			generator = null;
		} catch (Throwable e) {
			// e.printStackTrace();
			throw Warning.getWarning(e);
		}
	}

	public synchronized String getEncString(String strMing, String key) {
		setKey(key);
		String result = getEncString(strMing);
		setKey(KEY_LOCK);
		return result;
	}

	public synchronized String getDesString(String strMi, String key) {
		setKey(key);
		String result = getDesString(strMi);
		setKey(KEY_LOCK);
		return result;
	}

	/**
	 * 加密String明文输入,String密文输出
	 * 
	 * @param strMing
	 * @return
	 */
	public synchronized String getEncString(String strMing) {
		byte[] byteMi = null;
		byte[] byteMing = null;
		String strMi = "";
		// BASE64Encoder base64en = new BASE64Encoder();
		try {
			byteMing = strMing.getBytes("UTF-8");
			byteMi = this.getEncCode(byteMing);
			// strMi = base64en.encode(byteMi);
			strMi = Base64.getBASE64(byteMi);
		} catch (Throwable e) {
			// e.printStackTrace();
			// DebugUtil.error(e);
			throw Warning.getWarning(e);
		} finally {
			// base64en = null;
			byteMing = null;
			byteMi = null;
		}
		return strMi;
	}

	/**
	 * 解密 以String密文输入,String明文输出
	 * 
	 * @param strMi
	 * @return String
	 */
	public synchronized String getDesString(String strMi) {
		if (strMi == null || strMi.length() == 0)
			return "";
		// BASE64Decoder base64De = new BASE64Decoder();
		byte[] byteMing = null;
		byte[] byteMi = null;
		String strMing = "";
		try {
			// byteMi = base64De.decodeBuffer(strMi);
			byteMi = Base64.getFromBASE64(strMi);
			byteMing = this.getDesCode(byteMi);
			if (byteMing == null) // 不合法的转换
				return "";
			strMing = new String(byteMing, "UTF-8");
		} catch (Throwable e) {
			// e.printStackTrace();
			// DebugUtil.error(e);
			throw Warning.getWarning(e);
		} finally {
			// base64De = null;
			byteMing = null;
			byteMi = null;
		}
		return strMing;
	}

	/**
	 * 加密以byte[]明文输入,byte[]密文输出
	 * 
	 * @param byteS
	 * @return byte[]
	 */
	private byte[] getEncCode(byte[] byteS) {
		byte[] byteFina = null;
		Cipher cipher;
		try {
			cipher = Cipher.getInstance("DES");
			cipher.init(Cipher.ENCRYPT_MODE, key);
			byteFina = cipher.doFinal(byteS);
		} catch (Throwable e) {
			// e.printStackTrace();
			// DebugUtil.error(e);
			throw Warning.getWarning(e);
		} finally {
			cipher = null;
		}
		return byteFina;
	}

	/**
	 * 解密以byte[]密文输入,以byte[]明文输出
	 * 
	 * @param byteD
	 * @return byte[]
	 */
	private byte[] getDesCode(byte[] byteD) {
		Cipher cipher;
		byte[] byteFina = null;
		try {
			cipher = Cipher.getInstance("DES");
			cipher.init(Cipher.DECRYPT_MODE, key);
			byteFina = cipher.doFinal(byteD);
		} catch (Throwable e) {
			// e.printStackTrace();
			// DebugUtil.error(e);
			throw Warning.getWarning(e);
		} finally {
			cipher = null;
		}
		return byteFina;

	}

	public synchronized static DataDesUtil getInstance() {
		if (des == null)
			des = new DataDesUtil();
		return des;
	}

	public static void main(String[] args) {
		DataDesUtil des = new DataDesUtil();// 实例化一个对像
		des.setKey("suddenzhou|web|download");// 生成密匙

		String strEnc = des.getEncString("C:\\haiyan_error.log");// 加密字符串,返回String的密文
		System.out.println(strEnc);

		String strDes = des.getDesString(strEnc);// 把String 类型的密文解密
		System.out.println(strDes);

	}

}
//
// class BASE64Encoder extends CharacterEncoder {
//
// public BASE64Encoder() {
// }
//
// protected int bytesPerAtom() {
// return 3;
// }
//
// protected int bytesPerLine() {
// return 57;
// }
//
// protected void encodeAtom(OutputStream outputstream, byte abyte0[], int i,
// int j) throws IOException {
// if (j == 1) {
// byte byte0 = abyte0[i];
// int k = 0;
// // boolean flag = false;
// outputstream.write(pem_array[byte0 >>> 2 & 63]);
// outputstream.write(pem_array[(byte0 << 4 & 48) + (k >>> 4 & 15)]);
// outputstream.write(61);
// outputstream.write(61);
// } else if (j == 2) {
// byte byte1 = abyte0[i];
// byte byte3 = abyte0[i + 1];
// int l = 0;
// outputstream.write(pem_array[byte1 >>> 2 & 63]);
// outputstream
// .write(pem_array[(byte1 << 4 & 48) + (byte3 >>> 4 & 15)]);
// outputstream.write(pem_array[(byte3 << 2 & 60) + (l >>> 6 & 3)]);
// outputstream.write(61);
// } else {
// byte byte2 = abyte0[i];
// byte byte4 = abyte0[i + 1];
// byte byte5 = abyte0[i + 2];
// outputstream.write(pem_array[byte2 >>> 2 & 63]);
// outputstream
// .write(pem_array[(byte2 << 4 & 48) + (byte4 >>> 4 & 15)]);
// outputstream
// .write(pem_array[(byte4 << 2 & 60) + (byte5 >>> 6 & 3)]);
// outputstream.write(pem_array[byte5 & 63]);
// }
// }
//
// private static final char pem_array[] = { 'A', 'B', 'C', 'D', 'E', 'F',
// 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
// 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
// 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
// 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
// '6', '7', '8', '9', '_', '|' };
//
// }
//
// class BASE64Decoder extends CharacterDecoder {
//
// public BASE64Decoder() {
// decode_buffer = new byte[4];
// }
//
// protected int bytesPerAtom() {
// return 4;
// }
//
// protected int bytesPerLine() {
// return 72;
// }
//
// protected void decodeAtom(PushbackInputStream pushbackinputstream,
// OutputStream outputstream, int i) throws IOException {
// byte byte0 = -1;
// byte byte1 = -1;
// byte byte2 = -1;
// byte byte3 = -1;
// if (i < 2)
// throw new CEFormatException(
// "BASE64Decoder: Not enough bytes for an atom.");
// int j;
// do {
// j = pushbackinputstream.read();
// if (j == -1)
// throw new CEStreamExhausted();
// } while (j == 10 || j == 13);
// decode_buffer[0] = (byte) j;
// j = readFully(pushbackinputstream, decode_buffer, 1, i - 1);
// if (j == -1)
// throw new CEStreamExhausted();
// if (i > 3 && decode_buffer[3] == 61)
// i = 3;
// if (i > 2 && decode_buffer[2] == 61)
// i = 2;
// switch (i) {
// case 4: // '\004'
// byte3 = pem_convert_array[decode_buffer[3] & 255];
// // fall through
//
// case 3: // '\003'
// byte2 = pem_convert_array[decode_buffer[2] & 255];
// // fall through
//
// case 2: // '\002'
// byte1 = pem_convert_array[decode_buffer[1] & 255];
// byte0 = pem_convert_array[decode_buffer[0] & 255];
// // fall through
//
// default:
// switch (i) {
// case 2: // '\002'
// outputstream.write((byte) (byte0 << 2 & 252 | byte1 >>> 4 & 3));
// break;
//
// case 3: // '\003'
// outputstream.write((byte) (byte0 << 2 & 252 | byte1 >>> 4 & 3));
// outputstream
// .write((byte) (byte1 << 4 & 240 | byte2 >>> 2 & 15));
// break;
//
// case 4: // '\004'
// outputstream.write((byte) (byte0 << 2 & 252 | byte1 >>> 4 & 3));
// outputstream
// .write((byte) (byte1 << 4 & 240 | byte2 >>> 2 & 15));
// outputstream.write((byte) (byte2 << 6 & 192 | byte3 & 63));
// break;
// }
// break;
// }
// }
//
// private static final char pem_array[] = { 'A', 'B', 'C', 'D', 'E', 'F',
// 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
// 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
// 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
// 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
// '6', '7', '8', '9', '_', '|' };
//
// private static final byte pem_convert_array[];
//
// byte decode_buffer[];
//
// static {
// pem_convert_array = new byte[256];
// for (int i = 0; i < 255; i++)
// pem_convert_array[i] = -1;
//
// for (int j = 0; j < pem_array.length; j++)
// pem_convert_array[pem_array[j]] = (byte) j;
//
// }
// }